<?php

class InvestProgramPayout extends DataObject implements PermissionProvider {
    private static $singular_name = "Invest Program Payout";
    private static $plural_name = "Invest Program Payouts";

    private static $db = array(
    	'Debit' => 'Currency',
    	'Credit' => 'Currency',
    	'ForwardBalance' => 'Currency',
    	'Remark' => 'Varchar(250)'
    );
	
	private static $has_one = array(
		'Batch' => 'BonusBatch',
		'InvestProgram' => 'InvestProgram'
	);
	
	private static $many_many = array(
		'BonusAccounts' => 'BonusAccount',
		'ProductAccounts' => 'ProductAccount',
        'TradeCoinAccounts' => 'TradeCoinAccount',
        'UpgradeAccounts' => 'UpgradeAccount'
    );
	
	private static $default_sort = "Created DESC, ID DESC";
	
	private static $searchable_fields = array(
    	'InvestProgramID',
    	'Remark'
    );

    private static $summary_fields = array(
    	'Created.Nice',
        'AmountText',
        'ForwardBalance',
        'InvestProgram.ID',
        'Remark'
    );
	
	static function create_payout($programid, $batchid){
		$program = InvestProgram::get()->byID($programid);
		if($program && $program->DailyPayout > 0){
			$program_payout = InvestProgramPayout::create()
			->setField('Credit', $program->DailyPayout)
			->setField('BatchID', $batchid)
			->setField('InvestProgramID', $program->ID);
			$program_payout->write();
			return $program_payout;
		}
	}
	
	public function fieldLabels($includerelations = true) {
		$labels = parent::fieldLabels($includerelations);
		
		$labels['Created'] = _t('InvestProgramPayout.DATE', 'Date');
		$labels['Created.Nice'] = _t('InvestProgramPayout.DATE', 'Date');
		$labels['Debit'] = _t('InvestProgramPayout.DEBIT', 'Debit');
		$labels['Credit'] = _t('InvestProgramPayout.CREDIT', 'Credit');
		$labels['AmountText'] = _t('InvestProgramPayout.AMOUNT', 'Amount');
		$labels['ForwardBalance'] = _t('InvestProgramPayout.BALANCE', 'Balance');
		$labels['Remark'] = _t('InvestProgramPayout.REMAKR', 'Remark');
		$labels['Batch'] = _t('InvestProgramPayout.BATCH', 'Batch');
		$labels['BatchID'] = _t('InvestProgramPayout.BATCH', 'Batch');
		$labels['InvestProgram'] = _t('InvestProgramPayout.INVEST_PROGRAM', 'Invest Program');
		$labels['InvestProgramID'] = _t('InvestProgramPayout.INVEST_PROGRAM', 'Invest Program');
		$labels['InvestProgram.ID'] = _t('InvestProgramPayout.INVEST_PROGRAM_ID', 'Invest Program ID');
		$labels['BonusAccounts'] = _t('InvestProgramPayout.BONUS_ACCOUNT', 'E-Bonus Accounts');
        $labels['ProductAccounts'] = _t('InvestProgramPayout.PRODUCT_ACCOUNT', 'E-Product Accounts');
		$labels['TradeCoinAccounts'] = _t('InvestProgramPayout.TRADE_COIN_ACCOUNT', 'Trade-Coin Accounts');
		$labels['UpgradeAccounts'] = _t('InvestProgramPayout.UPGRADE_ACCOUNT', 'E-Upgrade Accounts');
		return $labels;	
	}
	
	function onBeforeWrite(){
		parent::onBeforeWrite();
		$this->setField('ForwardBalance', $this->getBalance() + $this->Credit - $this->Debit);
	}
	
	function onAfterWrite(){
		parent::onAfterWrite();
		if($this->InvestProgram()->OrderPackageID > 0 && !$this->InvestProgram()->Member()->NoInvestPayout){
			if($this->Credit > 0){
				if(!$count = $this->BonusAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => 'Bonus',
			            'Credit' => $this->Credit * 0.6,
			            'Reference' => $this->Batch()->Code,
			            'Description' => $this->Description
			        );
					
					if($this->InvestProgram()->Member()->IsExceedPayout){
						$statement_data['Credit'] = $statement_data['Credit'] * 0.5;
						
						$id = UpgradeAccount::create_statement($statement_data, $this->InvestProgram()->MemberID);
						$this->UpgradeAccounts()->add($id);
					}
					
			        $id = BonusAccount::create_statement($statement_data, $this->InvestProgram()->MemberID);
					$this->BonusAccounts()->add($id);
					
					$this->InvestProgram()->PaidDay += 1;
					if($this->InvestProgram()->PaidDay == $this->InvestProgram()->MaxDay && !$this->InvestProgram()->IsClosed){
						$this->InvestProgram()->IsClosed = 1;
					}
					else {
						$this->InvestProgram()->NextPayout = date("Y-m-d", strtotime("+1 day", strtotime($this->Batch()->Date)));
						$dw = date("w", strtotime($this->InvestProgram()->NextPayout));
						if($dw == 0){
							$this->InvestProgram()->NextPayout = strtotime("+1 day", strtotime($this->InvestProgram()->NextPayout));
						}
						else if($dw == 6){
							$this->InvestProgram()->NextPayout = strtotime("+2 day", strtotime($this->InvestProgram()->NextPayout));
						}
					}
					$this->InvestProgram()->TotalPayout += $this->Credit;
					$this->InvestProgram()->write();
				}
	
				if(!$count = $this->ProductAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => 'Bonus',
			            'Credit' => $this->Credit * 0.1,
			            'Reference' => $this->Batch()->Code,
			            'Description' => $this->Description
			        );
			        $id = ProductAccount::create_statement($statement_data, $this->InvestProgram()->MemberID);
					$this->ProductAccounts()->add($id);
				}
				
				if(!$count = $this->TradeCoinAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => 'Bonus',
			            'Credit' => $this->Credit * 0.3,
			            'Reference' => $this->Batch()->Code,
			            'Description' => $this->Description
			        );
			        $id = TradeCoinAccount::create_statement($statement_data, $this->InvestProgram()->MemberID);
					$this->TradeCoinAccounts()->add($id);
				}
			}

			if($this->Debit > 0){
				$statement = $this->BonusAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
				if($statement->count() > $this->BonusAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => $statement->Type,
			            'Debit' => $statement->Credit,
			            'Reference' => $statement->Reference,
			            'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
			        );
			        $id = BonusAccount::create_statement($statement_data, $statement->MemberID);
					$this->BonusAccounts()->add($id);
					$this->InvestProgram()->PaidDay -= 1;
					if($this->InvestProgram()->IsClosed){
						$this->InvestProgram()->IsClosed = 0;
					}
					$this->InvestProgram()->NextPayout = date("Y-m-d", strtotime("+1 day", strtotime($this->Batch()->Date)));
					$dw = date("w", strtotime($this->InvestProgram()->NextPayout));
					if($dw == 0){
						$this->InvestProgram()->NextPayout = strtotime("+1 day", strtotime($this->InvestProgram()->NextPayout));
					}
					else if($dw == 6){
						$this->InvestProgram()->NextPayout = strtotime("+2 day", strtotime($this->InvestProgram()->NextPayout));
					}
					$this->InvestProgram()->TotalPayout -= $statement->Credit;
					$this->InvestProgram()->write();
				}
				
				$statement = $this->UpgradeAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
				if($statement->count() > $this->UpgradeAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => $statement->Type,
			            'Debit' => $statement->Credit,
			            'Reference' => $statement->Reference,
			            'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
			        );
			        $id = UpgradeAccount::create_statement($statement_data, $statement->MemberID);
					$this->UpgradeAccounts()->add($id);
				}
				
				$statement = $this->ProductAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
				if($statement->count() > $this->ProductAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => $statement->Type,
			            'Debit' => $statement->Credit,
			            'Reference' => $statement->Reference,
			            'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
			        );
			        $id = ProductAccount::create_statement($statement_data, $statement->MemberID);
					$this->ProductAccounts()->add($id);
				}
				
				$statement = $this->TradeCoinAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
				if($statement->count() > $this->TradeCoinAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()){
					$statement_data = array(
			            'Type' => $statement->Type,
			            'Debit' => $statement->Credit,
			            'Reference' => $statement->Reference,
			            'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
			        );
			        $id = TradeCoinAccount::create_statement($statement_data, $statement->MemberID);
					$this->TradeCoinAccounts()->add($id);
				}
			}
		}
		else{
			if($this->Credit > 0){
				$this->InvestProgram()->PaidDay += 1;
				if($this->InvestProgram()->PaidDay == $this->InvestProgram()->MaxDay && !$this->InvestProgram()->IsClosed){
					$this->InvestProgram()->IsClosed = 1;
				}
				else {
					$this->InvestProgram()->NextPayout = date("Y-m-d", strtotime("+1 day", strtotime($this->Batch()->Date)));
					$dw = date("w", strtotime($this->InvestProgram()->NextPayout));
					if($dw == 0){
						$this->InvestProgram()->NextPayout = strtotime("+1 day", strtotime($this->InvestProgram()->NextPayout));
					}
					else if($dw == 6){
						$this->InvestProgram()->NextPayout = strtotime("+2 day", strtotime($this->InvestProgram()->NextPayout));
					}
				}
				$this->InvestProgram()->TotalPayout += $this->Credit;
				$this->InvestProgram()->write();
			}
		}
	}
	
	function getBalance(){
		return InvestProgramPayout::get()->filter('InvestProgram.MemberID', $this->InvestProgram()->MemberID)->sum('Credit') - InvestProgramPayout::get()->filter('InvestProgram.MemberID', $this->InvestProgram()->MemberID)->sum('Debit');
	}
	
	function getDescription(){
		return sprintf('FUND MANAGEMENT RETURN FOR Program ID #%s', $this->InvestProgramID);
	}

	function getAmountText(){
        if($this->Credit == $this->Debit){
			return DBField::create_field('Double', 0)->Nice();
		}
		else if($this->Credit > 0){
            return sprintf('%s(+)', DBField::create_field('Double', $this->Credit)->Nice());
        }
        else{
            return sprintf('%s(-)', DBField::create_field('Double', $this->Debit)->Nice());
        }
    }
	
    function canView($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check('VIEW_InvestProgramPayout');
    }

    function canEdit($member = false) {
    	if(!$this->exists() && $this->canCreate($member)){
    		return true;
    	}
        return false;
    }

    function canDelete($member = false) {
        return false;
    }

    function canCreate($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check('CREATE_InvestProgramPayout');
    }

    public function providePermissions() {
        return array(
            'VIEW_InvestProgramPayout' => array(
                'name' => _t('InvestProgramPayout.PERMISSION_VIEW', 'Allow view access right'),
                'category' => _t('InvestProgramPayout.PERMISSIONS_CATEGORY', 'Invest Program Payout')
            ),
            'CREATE_InvestProgramPayout' => array(
                'name' => _t('InvestProgramPayout.PERMISSION_CREATE', 'Allow create access right'),
                'category' => _t('InvestProgramPayout.PERMISSIONS_CATEGORY', 'Invest Program Payout')
            )
        );
    }

}
?>